home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
ftpser1a
/
ftp_srv2.bas
< prev
next >
Wrap
BASIC Source File
|
1999-10-04
|
20KB
|
560 lines
Attribute VB_Name = "FTP_Srv2"
Option Explicit
Sub ServerLog(ByVal Str As String)
FtpServ.LogWnd.AddItem Str
FtpServ.LogWnd.Selected(FtpServ.LogWnd.ListCount - 1) = True
End Sub
'EXEC A FTP COMMAND:
'<id_user> is a number in the range 1 to MAX_N_USERS
'identifing the user who sends the command;
'<cmd> is the command.
Function exec_FTP_cmd(Id_User As Integer, cmd As String) As Integer
Dim Kwrd As String 'keyword
Dim Argument(5) As String 'arguments
Dim ArgN As Long
Dim FTP_Err As Integer 'error
Dim PathName As String, Drv As String
Dim Full_Name As String 'pathname & file name
Dim File_Len As Long 'file lenght in bytes
Dim i As Long
Dim Ok As Integer
Dim Buffer As String
Dim DummyS As String
'variables used during the data exchange
Dim ExecSlot As Integer
Dim NewSockAddr As SockAddr, LclSockAddr As SockAddr
On Error Resume Next 'routine for error interception
FTP_Err = sintax_ctrl(cmd, Kwrd, Argument())
'log commands
ServerLog "<" & Format$(Id_User, "000") & "> " & Format$(Date$, "dd/mm/yy ") & Format$(Time$, "hh:mm - ") & cmd
If FTP_Err <> 0 Then
retf = send_reply(sintax_error_list(FTP_Err), Id_User)
Exit Function
End If
Select Case UCase$(Kwrd)
Case "USER": 'USER <username>
Ok = False
Debug.Print N_RECOGNIZED_USERS;
For i = 1 To N_RECOGNIZED_USERS
'Debug.Print UserIDs.No(i).Name
'controls if the user is in the list of known users
If Argument(0) = UserIDs.No(i).Name Then
'the user must enter a password but anonymous users can be accepted
If UserIDs.No(i).Name = "anonymous" Then
retf = send_reply("331 User anonymous accepted, please type your e-mail address as password.", Id_User)
Else
retf = send_reply("331 User name Ok, type in your password.", Id_User)
End If
users(Id_User).list_index = i
users(Id_User).cur_dir = UserIDs.No(i).Home
users(Id_User).state = 1
Ok = True
Exit For
End If
Next
If Not Ok Then 'unknown user
retf = send_reply("530 Not logged in, user " & Argument(0) & " is unknown.", Id_User)
retf = logoff(Id_User)
End If
Case "PASS": 'PASS <password>
If users(Id_User).state = 1 Then
If LCase(UserIDs.No(users(Id_User).list_index).Name) = "anonymous" Then
'anonymous user
retf = send_reply("230 User anonymous logged in, proceed.", Id_User)
users(Id_User).state = 2
Else
If Argument(0) = UserIDs.No(users(Id_User).list_index).Pass Then
'correct password, the user can proceed
retf = send_reply("230 User logged in, proceed.", Id_User)
users(Id_User).state = 2
Else
'wrong password, the user is disconnected
retf = send_reply("530 Not logged in, wrong password.", Id_User)
retf = logoff(Id_User)
End If
End If
Else
'the user must enter his name
retf = send_reply("503 I need your username.", Id_User)
End If
Case "CWD", "XCWD": 'CWD <pathname>
If users(Id_User).state = 2 Then
PathName = ChkPath(Id_User, Argument(0))
Drv = Left(PathName, 2)
ChDrive Drv
ChDir PathName
If Err.Number = 0 Then
users(Id_User).cur_dir = CurDir
'existing directory
retf = send_reply("250 CWD command executed.", Id_User)
ElseIf (Err.Number > 51 And Err.Number < 77) Or (Err.Number > 707 And Err.Number < 732) Then
'no existing directory
retf = send_reply("550 CWD command not executed: " & Error$, Id_User)
Else
'FtpServ.StatusBar.panels(1) = "Error " & CStr(Err) & " occurred."
retf = logoff(Id_User)
'End
End If
Else
'user not logged in
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "CDUP", "XCUP": 'CDUP
If users(Id_User).state = 2 Then
ChDir users(Id_User).cur_dir
ChDir ".."
users(Id_User).cur_dir = CurDir
retf = send_reply("200 CDUP command executed.", Id_User)
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "QUIT": 'QUIT
retf = logoff(Id_User)
Case "PORT": 'PORT <host-port>
If users(Id_User).state = 2 Then
'opens a data connection
ExecSlot = Socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
If ExecSlot < 0 Then
'error
retf = send_reply("425 Can't build data connection.", Id_User)
Else
NewSockAddr.sin_family = PF_INET
'remote IP address
IPLong.Byte4 = Val(Argument(0))
IPLong.Byte3 = Val(Argument(1))
IPLong.Byte2 = Val(Argument(2))
IPLong.Byte1 = Val(Argument(3))
CopyMemory i, IPLong, 4
NewSockAddr.sin_addr = i
'remote port
ArgN = Val(Argument(4))
NewSockAddr.sin_port = htons(ArgN)
retf = connect(ExecSlot, NewSockAddr, 16)
If retf < 0 Then
retf = send_reply("425 Can't build data connection.", Id_User)
Else
retf = send_reply("200 PORT command executed.", Id_User)
'stores the IP-address and port number in user record
users(Id_User).data_slot = ExecSlot
users(Id_User).IP_address = Argument(0) & "." & Argument(1) & "." & Argument(2) & "." & Argument(3)
users(Id_User).Port = Val(Argument(4))
ServerLog ("IP=" & users(Id_User).IP_address & ":" & Argument(4))
'<state> field establishes that now is
'possible to exec commands requiring a data connection
users(Id_User).state = 3
End If
End If
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "TYPE": 'TYPE <type-code>
If users(Id_User).state = 2 Then
'stores the access parameters in user record
retf = send_reply("200 TYPE command executed.", Id_User)
users(Id_User).data_representation = Argument(0)
users(Id_User).data_format_ctrls = Argument(1)
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "STRU": 'STRU <structure-code>
If users(Id_User).state = 2 Then
'stores access parameters in the user record
retf = send_reply("200 STRU command executed.", Id_User)
users(Id_User).data_structure = Argument(0)
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "MODE": 'MODE <mode-code>
If users(Id_User).state = 2 Then
'stores access parameters in the user record
retf = send_reply("200 MODE command executed.", Id_User)
users(Id_User).data_tx_mode = Argument(0)
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "RETR": 'RETR <pathname>
If users(Id_User).state = 3 Then
Full_Name = ChkPath(Id_User, Argument(0))
'file exist?
i = FileLen(Full_Name)
If Err.Number = 0 Then 'Yes
'controls access rights
DummyS = UserIDs.No(users(Id_User).list_index).Priv(1).Accs
If InStr(DummyS, "R") Then
retf = open_data_connect(Id_User)
'initializes record which contains file parameters
files_info(Id_User).Full_Name = Full_Name
files_info(Id_User).data_representation = users(Id_User).data_representation
files_info(Id_User).open_file = False
files_info(Id_User).retr_stor = 0
'enables timer to send data on connection
FtpServ.Timer1(Id_User).Enabled = True
Else
'the user can't retrieves files
retf = send_reply("550 You can't take this file action.", Id_User)
retf = close_data_connect(Id_User)
End If
ElseIf (Err.Number > 51 And Err.Number < 77) Or (Err.Number > 707 And Err.Number < 732) Then
'no existing file
retf = send_reply("550 RETR command not executed: " & Error$, Id_User)
retf = close_data_connect(Id_User)
Else
FtpServ.StatusBar.Panels(1) = "Error " & Err.Number & " occurred."
retf = close_data_connect(Id_User)
retf = logoff(Id_User)
'End
End If
ElseIf users(Id_User).state = 2 Then
retf = send_reply("425 Can't open data connection.", Id_User)
Else
retf = send_reply("530 User not logged in.", Id_User)
End If
Case "STOR": 'STOR <pathname>
If users(Id_Us